package com.gxc.integer;

import java.util.ArrayList;
import java.util.List;

/**
 * 22. 括号生成
 * 数字 n 代表生成括号的对数，请你设计一个函数，用于能够生成所有可能的并且 有效的 括号组合。
 */
public class GenerateParenthesis {

    public static void main(String[] args) {
        println(handle(3));

        System.out.println("------------");
        println(handle(1));
    }

    public static List<String> handle(int n) {
        List<String> list = new ArrayList<>();
        recursion(list, 0, 0, n, new StringBuilder());
        return list;
    }

    public static void recursion(List<String> list, int left, int right, int n, StringBuilder builder) {
        if (right == n) {
            list.add(builder.toString());
            return;
        }
        if (left == n) {
            recursion(list, left, right+1, n, builder.append(")"));
        } else if (left>right){
            StringBuilder rightBuilder = new StringBuilder();
            rightBuilder.append(builder.toString());
            recursion(list, left, right+1, n, rightBuilder.append(")"));

            StringBuilder leftBuilder = new StringBuilder();
            leftBuilder.append(builder.toString());
            recursion(list, left+1, right, n, leftBuilder.append("("));
        } else if (left==right){
            recursion(list, left+1, right, n, builder.append("("));
        }
    }

    private static void println(List<String> list) {
        list.forEach(System.out::println);
    }

    //回溯法
    class Solution {
        public List<String> generateParenthesis(int n) {
            List<String> ans = new ArrayList<String>();
            backtrack(ans, new StringBuilder(), 0, 0, n);
            return ans;
        }

        public void backtrack(List<String> ans, StringBuilder cur, int open, int close, int max) {
            if (cur.length() == max * 2) {
                ans.add(cur.toString());
                return;
            }
            if (open < max) {
                cur.append('(');
                backtrack(ans, cur, open + 1, close, max);
                cur.deleteCharAt(cur.length() - 1);
            }
            if (close < open) {
                cur.append(')');
                backtrack(ans, cur, open, close + 1, max);
                cur.deleteCharAt(cur.length() - 1);
            }
        }
    }

    //按括号序列的长度递归
    class Solution2 {
        ArrayList[] cache = new ArrayList[100];

        public List<String> generate(int n) {
            if (cache[n] != null) {
                return cache[n];
            }
            ArrayList<String> ans = new ArrayList<String>();
            if (n == 0) {
                ans.add("");
            } else {
                for (int c = 0; c < n; ++c) {
                    for (String left: generate(c)) {
                        for (String right: generate(n - 1 - c)) {
                            ans.add("(" + left + ")" + right);
                        }
                    }
                }
            }
            cache[n] = ans;
            return ans;
        }

        public List<String> generateParenthesis(int n) {
            return generate(n);
        }
    }


}
